#ifndef __DOOR_BLOCK_H__
#define __DOOR_BLOCK_H__

#include "Block.hpp"
#include "Engine/Vector3.hpp"
#include "Engine/Matrix.h"

using namespace PocketSurvival::Engine;

namespace PocketSurvival
{
    class SubsystemTerrain;
    class BlocksManager;
    struct ComponentMiner;

    // 门基类, 未完成...  未添加电路支持
    class DoorBlock : public Block
    {
    protected:
        SubsystemTerrain *m_subsystemTerrain;

    public:
        DoorBlock();
        virtual void initialize() override;
        virtual BlockPlacementData getPlacementValue(ComponentMiner *componentMiner, int32_t value, const TerrainRaycastResult &raycastResult) override;

        static bool IsTopPart(int32_t x, int32_t y, int32_t z);
        static bool IsBottomPart(int32_t x, int32_t y, int32_t z);

        static inline int32_t GetRotation(int32_t data);
        static inline bool GetOpen(int32_t data);
        static inline bool GetRightHanded(int32_t data);
        static inline int32_t SetRotation(int32_t data, int32_t rotation);
        static inline int32_t SetOpen(int32_t data, bool open);
        static inline int32_t SetRightHanded(int32_t data, bool rightHanded);
        static inline int32_t GetHingeFace(int32_t data);
    };

    inline int32_t DoorBlock::GetRotation(int32_t data)
    {
        return data & 3;
    }
    inline bool DoorBlock::GetOpen(int32_t data)
    {
        return (data & 4) != 0;
    }
    inline bool DoorBlock::GetRightHanded(int32_t data)
    {
        return (data & 8) == 0;
    }
    inline int32_t DoorBlock::SetRotation(int32_t data, int32_t rotation)
    {
        return (data & -4) | (rotation & 3);
    }
    inline int32_t DoorBlock::SetOpen(int32_t data, bool open)
    {
        if (!open)
        {
            return data & -5;
        }
        return data | 4;
    }
    inline int32_t DoorBlock::SetRightHanded(int32_t data, bool rightHanded)
    {
        if (rightHanded)
        {
            return data & -9;
        }
        return data | 8;
    }

    inline int32_t DoorBlock::GetHingeFace(int32_t data)
    {
        int32_t rotation = GetRotation(data);
        int32_t num = (rotation - 1 < 0) ? 3 : (rotation - 1);
        if (GetRightHanded(data) == false)
        {
            num = CellFace::OppositeFace(num);
        }
        return num;
    }

} // namespace PocketSurvival

#endif
